package compressFiles.agent;

import jetbrains.buildServer.RunBuildException;
import jetbrains.buildServer.agent.*;
import jetbrains.buildServer.util.*;
import org.jetbrains.annotations.*;

import javax.naming.spi.DirectoryManager;
import java.io.*;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ZipBuildProcess extends FutureBasedBuildProcess
{
    @NotNull
    private final AgentRunningBuild myBuild;
    @NotNull
    private final BuildRunnerContext myContext;

    public ZipBuildProcess(@NotNull final AgentRunningBuild build, @NotNull final BuildRunnerContext context)
    {
        myBuild = build;
        myContext = context;
    }

    private String getParameter(@NotNull final String parameterName)
    {
        final String value = myContext.getRunnerParameters().get(parameterName);
        if (value == null || value.trim().length() == 0) return null;
        String result = value.trim();
        return result;
    }

    @NotNull
    public BuildFinishedStatus call() throws Exception
    {
        try
        {
            final BuildProgressLogger logger = myBuild.getBuildLogger();
            String toZip = getParameter("folderPath");
            String output = getParameter("zipPath");

            logger.progressMessage("FolderPath: " + toZip);
            logger.progressMessage("ZipPath: " + output);

            ZipOutputStream zip = new ZipOutputStream(new FileOutputStream(output));
            File dir = new File(toZip);
            dir.delete();

            if (dir.isDirectory())
            {
                DoZipWork(logger, "", zip, dir);
                zip.close();
            }
            else
            {
                zip.close();
                throw new RunBuildException("The Folder path provided is not a folder");
            }

            return BuildFinishedStatus.FINISHED_SUCCESS;
        }
        catch (Exception e)
        {
            return BuildFinishedStatus.FINISHED_FAILED;
        }
    }

    private void DoZipWork(BuildProgressLogger logger, String relativePath, ZipOutputStream zip, File currDirectory) throws IOException
    {
        String[] entries = currDirectory.list();
        byte[] buffer = new byte[4096]; // Create a buffer for copying
        int bytesRead;

        logger.progressMessage("Working On: " + currDirectory.getAbsolutePath());
        for (int i = 0; i < entries.length; i++)
        {
            File f = new File(currDirectory, entries[i]);
            if (f.isDirectory())
                DoZipWork(logger, relativePath + f.getName() + "/", zip, f);
            else
            {
                String path = "";
                if(relativePath.trim().length() == 0)
                    path = f.getName();
                else
                    path = relativePath + f.getName();

                logger.progressMessage("Compresssing File: " + path);
                FileInputStream in = new FileInputStream(f); // Stream to read file
                ZipEntry entry = new ZipEntry(path); // Make a ZipEntry
                zip.putNextEntry(entry); // Store entry
                while ((bytesRead = in.read(buffer)) != -1)
                    zip.write(buffer, 0, bytesRead);

                in.close();
            }
        }
    }
}
